Latest Date of Dataset: 2020-04-17
Updated: 2020-04-18 19:43:34 EST
This dashboard is used to track the current progress of the COVID-19 pandemic throughout the world. The visualization and information presented are automatically updated daily with current data scraped from the Johns Hopkin’s COVID-19 Data Repository. Their data is retrieved from offical sources such as World Health Organization (WHO), China CDC, US CDC, and more.
The data is cleaned and aggregated through R, formatted in Rmarkdown, and exported as an HTML document to be hosted through GitPages. The source R notebook can be found at covid19-daily-dashboard.Rmd in the GitHub repository.
Overview of Cases (2020-04-17)
Below is an interactive plot displaying the number of confirmed, dead, and recovered cases per country and province if data is specified. The data was aggregated from the Johns Hopkins’s data repository and this notebook is set to run nightly to provide up to date results
NaNs produced
Confirmed Cases per Country
The table below shows aggregated data of each country’s confirmed, recovered, and dead population. Each column can be sorted to view least or most of each status. The graphs below show the total and daily count of confirmed cases for the countries with the most cases and are tracked by days since the first reported case. Each graph has two seperate views - one with total count and another with % of country’s population. The population data is retrived from the United Nations.
(*China’s data is removed since dataset does not track prior to 22Jan20 therefore does not align with other countries)
COVID19 Cases Spread Timelapse
The time-lapse was produced through gganimate and shows the spread of the virus since 22Jan2020. The time-lapse cycles through the dates, showing the color coded increase of confirmed, recovered, and death cases across the world.

New Cases of the Day (2020-04-17)
The ‘New Cases of the Day’ map displays all confirmed cases of the specified date. The map was produced through Leaflet and provides a detailed and interactive map that shows the location and number of cases of the day.
Also, to differentiate if the case of the day is the first case in the specified location, it is highlighted red. All the specified points on the map are listed in the table below, including cumulative count of each location.
New Cases of the Week (2020-04-17)
The ‘New Cases of the Week’ map displays all confirmed cases of the week starting from the specified date. This map shows the same information as the daily cases map but includes all cases in the past week.
General Trends
The plots below outlines general trends seen of the virus over time:
“Percent of Cases Recovered or Dead per Day”: the total percent of cases that have resulted in recovery or death per confirmed case
“Cumulative Status of All Cases”: the continuous increase of confirmed, death, and recovered cases over time
“Status of Cases per Day”: the number of cases classified as confirmed, death, or recovered subtracted to show per day changes



LS0tDQp0aXRsZTogIkNPVklEMTkgRGFpbHkgRGFzaGJvYXJkIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQogICAgDQotLS0NCg0KYGBge3IgU2V0dXAsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojIEludGVyYWN0aW9uDQpsaWJyYXJ5KHJ2ZXN0KQ0KbGlicmFyeShyc3R1ZGlvYXBpKQ0KbGlicmFyeShkcmF0KQ0KbGlicmFyeShnaXQycikNCg0KIyBBZ2dyZWdhdGlvbg0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkodGlkeXIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShEVCkNCg0KIyBWaXN1YWxpemF0aW9ucw0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShsZWFmbGV0KQ0KbGlicmFyeShnZ3RoZW1lcykNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShtYXBzKQ0KbGlicmFyeShwbmcpDQpsaWJyYXJ5KGdpZnNraSkNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShyYW5kb21jb2xvUikNCmBgYA0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30NCmxpbmsgPC0gImh0dHBzOi8vZ2l0aHViLmNvbS8vQ1NTRUdJU2FuZERhdGEvQ09WSUQtMTkvcmF3L21hc3Rlci9jc3NlX2NvdmlkXzE5X2RhdGEvY3NzZV9jb3ZpZF8xOV90aW1lX3Nlcmllcy8iDQpjc3ZfbGlzdCA8LSBjKA0KICAidGltZV9zZXJpZXNfY292aWQxOV9jb25maXJtZWRfZ2xvYmFsLmNzdiIsDQogICJ0aW1lX3Nlcmllc19jb3ZpZDE5X2RlYXRoc19nbG9iYWwuY3N2IiwNCiAgInRpbWVfc2VyaWVzX2NvdmlkMTlfcmVjb3ZlcmVkX2dsb2JhbC5jc3YiDQopDQoNCg0KZm9yIChjc3YgaW4gY3N2X2xpc3QpIHsNCiAgcGF0aCA8LSBwYXN0ZShsaW5rLCBjc3YsIHNlcCA9ICIiKQ0KICBkb3dubG9hZF9wYXRoIDwtIHBhc3RlKCJkYXRhX3Jhdy8iLCBjc3YsIHNlcCA9ICIiKQ0KICBkb3dubG9hZC5maWxlKHBhdGgsIGRlc3RmaWxlID0gZG93bmxvYWRfcGF0aCkNCn0NCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmN2X2NvbiA8LSByZWFkX2NzdigiZGF0YV9yYXcvdGltZV9zZXJpZXNfY292aWQxOV9jb25maXJtZWRfZ2xvYmFsLmNzdiIpICU+JQ0KICBnYXRoZXIoa2V5ID0gIkRhdGUiLCB2YWx1ZSA9IENvbmZpcm1lZCwgLUxhdCwgLUxvbmcsIC1gUHJvdmluY2UvU3RhdGVgLCAtYENvdW50cnkvUmVnaW9uYCkNCg0KY3ZfZGVkIDwtIHJlYWRfY3N2KCJkYXRhX3Jhdy90aW1lX3Nlcmllc19jb3ZpZDE5X2RlYXRoc19nbG9iYWwuY3N2IikgJT4lDQogIGdhdGhlcihrZXkgPSAiRGF0ZSIsIHZhbHVlID0gRGVhZCwgLUxhdCwgLUxvbmcsIC1gUHJvdmluY2UvU3RhdGVgLCAtYENvdW50cnkvUmVnaW9uYCkNCg0KY3ZfcmVjIDwtIHJlYWRfY3N2KCJkYXRhX3Jhdy90aW1lX3Nlcmllc19jb3ZpZDE5X3JlY292ZXJlZF9nbG9iYWwuY3N2IikgJT4lDQogIGdhdGhlcihrZXkgPSAiRGF0ZSIsIHZhbHVlID0gUmVjb3ZlcmVkLCAtTGF0LCAtTG9uZywgLWBQcm92aW5jZS9TdGF0ZWAsIC1gQ291bnRyeS9SZWdpb25gKQ0KDQpjb3VudHJ5X3BvcCA8LSByZWFkX2NzdigiZGF0YV9yYXcvY291bnRyeV9wb3B1bGF0aW9uLmNzdiIpDQpgYGANCg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmN2X21lcmdlIDwtIG1lcmdlKGN2X2NvbiwgY3ZfZGVkLCBieSA9IGMoIlByb3ZpbmNlL1N0YXRlIiwgIkxhdCIsICJMb25nIiwgIkNvdW50cnkvUmVnaW9uIiwgIkRhdGUiKSwgYWxsID0gVFJVRSkgJT4lDQogIG1lcmdlKGN2X3JlYywgYnkgPSBjKCJQcm92aW5jZS9TdGF0ZSIsICJMYXQiLCAiTG9uZyIsICJDb3VudHJ5L1JlZ2lvbiIsICJEYXRlIiksIGFsbCA9IFRSVUUpICU+JQ0KICByZW5hbWUoIkNvdW50cnlfUmVnaW9uIiA9ICJDb3VudHJ5L1JlZ2lvbiIpICU+JQ0KICByZW5hbWUoIlByb3ZpbmNlX1N0YXRlIiA9ICJQcm92aW5jZS9TdGF0ZSIpDQpjdl9tZXJnZSREYXRlIDwtIGFzLkRhdGUoY3ZfbWVyZ2UkRGF0ZSwgZm9ybWF0ID0gIiVtLyVkLyV5IikNCg0KY3YgPC0gZ2F0aGVyKGN2X21lcmdlLCBrZXkgPSAiU3RhdHVzIiwgdmFsdWUgPSBDb3VudCwgLURhdGUsIC1MYXQsIC1Mb25nLCAtUHJvdmluY2VfU3RhdGUsIC1Db3VudHJ5X1JlZ2lvbikNCmN2IDwtIGN2W3dpdGgoY3YsIG9yZGVyKENvdW50cnlfUmVnaW9uLCBQcm92aW5jZV9TdGF0ZSwgU3RhdHVzLCBEYXRlKSksIF0NCmBgYA0KDQoNCg0KYGBge3IgZnVuY3Rpb25fY2hlY2tfZmlyc3RfY2FzZSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNoZWNrX2NvbnRpbnVvdXMgPC0gZnVuY3Rpb24oeCwgY3YsIG51bV9wcmV2KSB7DQogIGlmICgNCiAgICAoY3YkTG9uZ1t4XSAhPSBjdiRMb25nW3ggLSBudW1fcHJldl0pIHx8DQogICAgICAoY3YkTGF0W3hdICE9IGN2JExhdFt4IC0gbnVtX3ByZXZdKSB8fA0KICAgICAgKGN2JFN0YXR1c1t4XSAhPSBjdiRTdGF0dXNbeCAtIG51bV9wcmV2XSkpIHsNCiAgICBjb250IDwtICJOIg0KICB9DQogIGVsc2Ugew0KICAgIGNvbnQgPC0gIlkiDQogIH0NCiAgcmV0dXJuKGNvbnQpDQp9DQoNCg0KZGFpbHlfd2Vla2x5X2NvdW50ZXIgPC0gZnVuY3Rpb24oY3YpIHsNCiAgZm9yICh4IGluIHNlcSgxLCBucm93KGN2KSkpIHsNCiAgICBpZiAoeCA9PSAxKSB7DQogICAgICBjdiREYWlseV9Db3VudFt4XSA8LSBOQQ0KICAgICAgY3YkV2Vla2x5X0NvdW50W3hdIDwtIE5BDQogICAgfQ0KICAgIGVsc2UgaWYgKGNoZWNrX2NvbnRpbnVvdXMoeCwgY3YsIDEpID09ICJOIikgew0KICAgICAgY3YkRGFpbHlfQ291bnRbeF0gPC0gTkENCiAgICAgIGN2JFdlZWtseV9Db3VudFt4XSA8LSBOQQ0KICAgIH0NCiAgICBlbHNlIGlmICh4IDw9IDcpIHsNCiAgICAgIGN2JERhaWx5X0NvdW50W3hdIDwtIChjdiRDb3VudFt4XSkgLSAoY3YkQ291bnRbeCAtIDFdKQ0KICAgICAgY3YkV2Vla2x5X0NvdW50W3hdIDwtIE5BDQogICAgfQ0KICAgIGVsc2UgaWYgKChjaGVja19jb250aW51b3VzKHgsIGN2LCAxKSA9PSAiWSIpICYmDQogICAgICAoY2hlY2tfY29udGludW91cyh4LCBjdiwgNykgPT0gIk4iKSkgew0KICAgICAgY3YkRGFpbHlfQ291bnRbeF0gPC0gKGN2JENvdW50W3hdKSAtIChjdiRDb3VudFt4IC0gMV0pDQogICAgICBjdiRXZWVrbHlfQ291bnRbeF0gPC0gTkENCiAgICB9DQogICAgZWxzZSBpZiAoKGNoZWNrX2NvbnRpbnVvdXMoeCwgY3YsIDcpID09ICJZIikpIHsNCiAgICAgIGN2JERhaWx5X0NvdW50W3hdIDwtIChjdiRDb3VudFt4XSkgLSAoY3YkQ291bnRbeCAtIDFdKQ0KICAgICAgY3YkV2Vla2x5X0NvdW50W3hdIDwtIChjdiRDb3VudFt4XSkgLSAoY3YkQ291bnRbeCAtIDddKQ0KICAgIH0NCiAgfQ0KICByZXR1cm4oY3YpDQp9DQpgYGANCg0KDQpgYGB7ciwgYXBwbHlfY2hlY2tfY2FzZSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmN2IDwtIGRhaWx5X3dlZWtseV9jb3VudGVyKGN2KQ0KbGF0ZXN0X2RhdGUgPC0gYXMuRGF0ZShTeXMuRGF0ZSgpKSAtIDENCiNsYXRlc3RfZGF0ZSA8LSBzb3J0KGN2JERhdGUsIGRlY3JlYXNpbmcgPSBUUlVFKVsxXSAtIDENCmN2IDwtIGZpbHRlcihjdiwgRGF0ZSA8PSBsYXRlc3RfZGF0ZSkNCmBgYA0KDQojIyMjIyBMYXRlc3QgRGF0ZSBvZiBEYXRhc2V0OiBgciBsYXRlc3RfZGF0ZWANCiMjIyMjIyBVcGRhdGVkOiBgciBTeXMudGltZSgpYCBFU1QNCg0KVGhpcyBkYXNoYm9hcmQgaXMgdXNlZCB0byB0cmFjayB0aGUgY3VycmVudCBwcm9ncmVzcyBvZiB0aGUgQ09WSUQtMTkgcGFuZGVtaWMgdGhyb3VnaG91dCB0aGUgd29ybGQuIFRoZSB2aXN1YWxpemF0aW9uIGFuZCBpbmZvcm1hdGlvbiBwcmVzZW50ZWQgYXJlIGF1dG9tYXRpY2FsbHkgdXBkYXRlZCBkYWlseSB3aXRoIGN1cnJlbnQgZGF0YSBzY3JhcGVkIGZyb20gdGhlIFtKb2hucyBIb3BraW7igJlzIENPVklELTE5IERhdGEgUmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL0NTU0VHSVNhbmREYXRhL0NPVklELTE5KS4gVGhlaXIgZGF0YSBpcyByZXRyaWV2ZWQgZnJvbSBvZmZpY2FsIHNvdXJjZXMgc3VjaCBhcyBXb3JsZCBIZWFsdGggT3JnYW5pemF0aW9uIChXSE8pLCBDaGluYSBDREMsIFVTIENEQywgYW5kIG1vcmUuDQoNClRoZSBkYXRhIGlzIGNsZWFuZWQgYW5kIGFnZ3JlZ2F0ZWQgdGhyb3VnaCBSLCBmb3JtYXR0ZWQgaW4gUm1hcmtkb3duLCBhbmQgZXhwb3J0ZWQgYXMgYW4gSFRNTCBkb2N1bWVudCB0byBiZSBob3N0ZWQgdGhyb3VnaCBHaXRQYWdlcy4gVGhlIHNvdXJjZSBSIG5vdGVib29rIGNhbiBiZSBmb3VuZCBhdCBbY292aWQxOS1kYWlseS1kYXNoYm9hcmQuUm1kXShodHRwczovL2dpdGh1Yi5jb20vYWxiZWNoZW4vY292aWQxOS1kYWlseS1kYXNoYm9hcmQvYmxvYi9tYXN0ZXIvY292aWQxOS1kYWlseS1kYXNoYm9hcmQuUm1kKSBpbiB0aGUgW0dpdEh1YiByZXBvc2l0b3J5XShodHRwczovL2dpdGh1Yi5jb20vYWxiZWNoZW4vY292aWQxOS1kYWlseS1kYXNoYm9hcmQpLg0KDQoNCmBgYHtyIGVtcHR5X2RmX2Z1bmN0aW9uLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZW1wdHlfZGYgPC0gZnVuY3Rpb24oKSB7DQogIGVtcHR5X2RmIDwtIGRhdGEuZnJhbWUoDQogICAgUHJvdmluY2VfU3RhdGUgPSBjaGFyYWN0ZXIoMCksDQogICAgTGF0ID0gZG91YmxlKCksIExvbmcgPSBkb3VibGUoKSwNCiAgICBDb3VudHJ5X1JlZ2lvbiA9IGNoYXJhY3RlcigwKSwNCiAgICBEYXRlID0gYXMuRGF0ZShjaGFyYWN0ZXIoKSksDQogICAgU3RhdHVzID0gY2hhcmFjdGVyKDApLA0KICAgIENvdW50ID0gZG91YmxlKCksDQogICAgRGFpbHlfQ291bnQgPSBkb3VibGUoKSwgV2Vla2x5X0NvdW50ID0gZG91YmxlKCkNCiAgKQ0KICBlbXB0eV9kZiRQcm92aW5jZV9TdGF0ZSA8LSBhcy5jaGFyYWN0ZXIoZW1wdHlfZGYkUHJvdmluY2VfU3RhdGUpDQogIGVtcHR5X2RmJENvdW50cnlfUmVnaW9uIDwtIGFzLmNoYXJhY3RlcihlbXB0eV9kZiRDb3VudHJ5X1JlZ2lvbikNCiAgZW1wdHlfZGYkU3RhdHVzIDwtIGFzLmNoYXJhY3RlcihlbXB0eV9kZiRTdGF0dXMpDQogIHJldHVybihlbXB0eV9kZikNCn0NCmBgYA0KDQoNCmBgYHtyIG5ld19jYXNlc19hZ2csIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpmaXJzdF9hbmRfbmV3X2Nhc2VzIDwtIGZ1bmN0aW9uKGN2LCBkYXlzKSB7DQogIGhpZ2hfZGF0ZSA8LSBzb3J0KGN2JERhdGUsIGRlY3JlYXNpbmcgPSBUUlVFKVsxXSAtIDENCiAgY3YgPC0gY3YgJT4lIA0KICAgIGZpbHRlcihTdGF0dXMgPT0gIkNvbmZpcm1lZCIsICFpcy5uYShDb3VudCkpDQogIGN2JEZpcnN0X0Nhc2UgPC0gRkFMU0UNCg0KICBmb3IgKHggaW4gc2VxKDEsIG5yb3coY3YpKSkgew0KICAgIGlmICgNCiAgICAgIChjdiREYXRlW3hdID09IGhpZ2hfZGF0ZSkgJiYNCiAgICAgICAgKGN2JENvdW50W3ggLSBkYXlzXSA9PSAwKSAmJg0KICAgICAgICAoY3YkQ291bnRbeF0gPiAwKQ0KICAgICkgew0KICAgICAgY3YkRmlyc3RfQ2FzZVt4XSA8LSBUUlVFDQogICAgfQ0KICB9DQoNCiAgbmV3X2Nhc2VzX2RmIDwtIGZpbHRlcihjdiwgRGF0ZSA9PSBoaWdoX2RhdGUpDQoNCiAgaWYgKGRheXMgPT0gMSkgew0KICAgIG5ld19jYXNlc19kZiA8LSBmaWx0ZXIobmV3X2Nhc2VzX2RmLCBEYWlseV9Db3VudCA+IDApDQogIH0NCiAgZWxzZSBpZiAoZGF5cyA9PSA3KSB7DQogICAgbmV3X2Nhc2VzX2RmIDwtIGZpbHRlcihuZXdfY2FzZXNfZGYsIFdlZWtseV9Db3VudCA+IDApDQogIH0NCg0KICByZXR1cm4obmV3X2Nhc2VzX2RmKQ0KfQ0KDQpuZXdfY2FzZXNfZGF5IDwtIGZpcnN0X2FuZF9uZXdfY2FzZXMoY3YsIDEpDQpuZXdfY2FzZXNfd2VlayA8LSBmaXJzdF9hbmRfbmV3X2Nhc2VzKGN2LCA3KQ0KYGBgDQoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpjdl9sYXRlc3QgPC0gZmlsdGVyKGN2X21lcmdlLCBEYXRlID09IGxhdGVzdF9kYXRlKQ0KY3ZfbGF0ZXN0IDwtIGN2X2xhdGVzdFt3aXRoKGN2X2xhdGVzdCwgb3JkZXIoLUNvbmZpcm1lZCwgLVJlY292ZXJlZCwgLURlYWQpKSwgXQ0KYGBgDQoNCiMjIyBPdmVydmlldyBvZiBDYXNlcyAoYHIgbGF0ZXN0X2RhdGVgKQ0KQmVsb3cgaXMgYW4gaW50ZXJhY3RpdmUgcGxvdCBkaXNwbGF5aW5nIHRoZSBudW1iZXIgb2YgY29uZmlybWVkLCBkZWFkLCBhbmQgcmVjb3ZlcmVkIGNhc2VzIHBlciBjb3VudHJ5IGFuZCBwcm92aW5jZSBpZiBkYXRhIGlzIHNwZWNpZmllZC4gVGhlIGRhdGEgd2FzIGFnZ3JlZ2F0ZWQgZnJvbSB0aGUgSm9obnMgSG9wa2lucydzIGRhdGEgcmVwb3NpdG9yeSBhbmQgdGhpcyBub3RlYm9vayBpcyBzZXQgdG8gcnVuIG5pZ2h0bHkgdG8gcHJvdmlkZSB1cCB0byBkYXRlIHJlc3VsdHMNCmBgYHtyIGZ1bGxfcGxvdCwgZWNobz1GQUxTRX0NCmN2X2xhdGVzdF9sYWJlbHMgPC0gZnVuY3Rpb24oZGYpIHsNCiAgbGFicyA8LSBsYXBwbHkoc2VxKG5yb3coZGYpKSwgZnVuY3Rpb24oaSkgew0KICAgIHBhc3RlMCgNCiAgICAgICJDb3VudHJ5OiAiLCBkZltpLCAiQ291bnRyeV9SZWdpb24iXSwgIjxicj4gIiwNCiAgICAgICJQcm92aW5jZTogIiwgZGZbaSwgIlByb3ZpbmNlX1N0YXRlIl0sICI8YnI+IiwNCiAgICAgICJDb25maXJtZWQ6ICIsIGRmW2ksICJDb25maXJtZWQiXSwgIjxicj4iLA0KICAgICAgIkRlYWQ6ICIsIGRmW2ksICJEZWFkIl0sICI8YnI+IiwNCiAgICAgICJSZWNvdmVyZWQ6ICIsIGRmW2ksICJSZWNvdmVyZWQiXSwgIjxicj4iLA0KICAgICAgIkRhdGU6ICIsIGRmW2ksICJEYXRlIl0NCiAgICApDQogIH0pDQp9DQoNCmxlYWZsZXQoZGF0YSA9IGN2X2xhdGVzdCwgd2lkdGggPSAiMTAwJSIpICU+JQ0KICBhZGRUaWxlcygpICU+JQ0KICBhZGRDaXJjbGVNYXJrZXJzKA0KICAgIGxhdCA9IH5MYXQsDQogICAgbG5nID0gfkxvbmcsDQogICAgcmFkaXVzID0gfiBsb2coQ29uZmlybWVkLCAxLjEpLzEwLA0KICAgIGxhYmVsID0gbGFwcGx5KGN2X2xhdGVzdF9sYWJlbHMoY3ZfbGF0ZXN0KSwgaHRtbHRvb2xzOjpIVE1MKQ0KICApDQpgYGANCg0KDQojIyMgQ29uZmlybWVkIENhc2VzIHBlciBDb3VudHJ5DQpUaGUgdGFibGUgYmVsb3cgc2hvd3MgYWdncmVnYXRlZCBkYXRhIG9mIGVhY2ggY291bnRyeSdzIGNvbmZpcm1lZCwgcmVjb3ZlcmVkLCBhbmQgZGVhZCBwb3B1bGF0aW9uLiBFYWNoIGNvbHVtbiBjYW4gYmUgc29ydGVkIHRvIHZpZXcgbGVhc3Qgb3IgbW9zdCBvZiBlYWNoIHN0YXR1cy4gVGhlIGdyYXBocyBiZWxvdyBzaG93IHRoZSB0b3RhbCBhbmQgZGFpbHkgY291bnQgb2YgY29uZmlybWVkIGNhc2VzIGZvciB0aGUgY291bnRyaWVzIHdpdGggdGhlIG1vc3QgY2FzZXMgYW5kIGFyZSB0cmFja2VkIGJ5IGRheXMgc2luY2UgdGhlIGZpcnN0IHJlcG9ydGVkIGNhc2UuIEVhY2ggZ3JhcGggaGFzIHR3byBzZXBlcmF0ZSB2aWV3cyAtIG9uZSB3aXRoIHRvdGFsIGNvdW50IGFuZCBhbm90aGVyIHdpdGggJSBvZiBjb3VudHJ5J3MgcG9wdWxhdGlvbi4gVGhlIHBvcHVsYXRpb24gZGF0YSBpcyByZXRyaXZlZCBmcm9tIHRoZSBbVW5pdGVkIE5hdGlvbnNdKGh0dHBzOi8vcG9wdWxhdGlvbi51bi5vcmcvd3BwL0Rvd25sb2FkL1N0YW5kYXJkL0NTVi8pLg0KDQoNCg0KKCpDaGluYSdzIGRhdGEgaXMgcmVtb3ZlZCBzaW5jZSBkYXRhc2V0IGRvZXMgbm90IHRyYWNrIHByaW9yIHRvIDIySmFuMjAgdGhlcmVmb3JlIGRvZXMgbm90IGFsaWduIHdpdGggb3RoZXIgY291bnRyaWVzKQ0KDQoNCmBgYHtyIGNvdW50cnlfdGFibGUsIGVjaG89RkFMU0V9DQpjb3VudHJ5X3RhYmxlIDwtIGN2X21lcmdlICU+JQ0KICBzZWxlY3QoQ291bnRyeV9SZWdpb24sIENvbmZpcm1lZCwgUmVjb3ZlcmVkLCBEZWFkLCBEYXRlKSAlPiUNCiAgZ3JvdXBfYnkoQ291bnRyeV9SZWdpb24pICU+JQ0KICBmaWx0ZXIoRGF0ZT09bGF0ZXN0X2RhdGUpICU+JQ0KICBzZWxlY3QoQ291bnRyeV9SZWdpb24sIENvbmZpcm1lZCwgUmVjb3ZlcmVkLCBEZWFkKSAlPiUNCiAgc3VtbWFyaXNlX2FsbChzdW0pDQpjb3VudHJ5X3RhYmxlIDwtIGNvdW50cnlfdGFibGVbd2l0aChjb3VudHJ5X3RhYmxlLCBvcmRlcigtQ29uZmlybWVkLCAtUmVjb3ZlcmVkLCAtRGVhZCkpLCBdDQoNCmNvdW50cnlfdGFibGUNCmBgYA0KDQpgYGB7ciBkZl9mb3JfdG9wX2NvdW50cmllcywgZWNobz1GQUxTRX0NCnRvcF8xMF9jb3VudHJpZXMgPC0gKGhlYWQoY291bnRyeV90YWJsZSRDb3VudHJ5X1JlZ2lvbiwgMTApKQ0KDQp0b3AxMF9kZiA8LSBjdiAlPiUNCiAgZmlsdGVyKChjdiRDb3VudHJ5X1JlZ2lvbiAlaW4lIGModG9wXzEwX2NvdW50cmllcykpICYgKGN2JFN0YXR1cyA9PSAnQ29uZmlybWVkJyksIChjdiRDb3VudHJ5X1JlZ2lvbiAhPSAnQ2hpbmEnKSkgJT4lDQogIHNlbGVjdChDb3VudHJ5X1JlZ2lvbiwgRGF0ZSwgQ291bnQsIERhaWx5X0NvdW50LCBXZWVrbHlfQ291bnQpICU+JQ0KICBncm91cF9ieShDb3VudHJ5X1JlZ2lvbiwgRGF0ZSkgJT4lDQogIHN1bW1hcmlzZShDb3VudCA9IHN1bShDb3VudCwgbmEucm0gPSBUUlVFKSwgRGFpbHlfQ291bnQgPSBzdW0oRGFpbHlfQ291bnQsIG5hLnJtID0gVFJVRSksIFdlZWtseV9Db3VudCA9IHN1bShXZWVrbHlfQ291bnQsIG5hLnJtID0gVFJVRSkpDQoNCg0KdG9wMTBfZGYgPC0gdG9wMTBfZGZbd2l0aCh0b3AxMF9kZiwgb3JkZXIoQ291bnRyeV9SZWdpb24sIERhdGUpKSwgXQ0KdG9wMTBfZGYkYERheXMgU2luY2UgRmlyc3QgQ2FzZWAgPC0gMA0KDQpmb3IgKHggaW4gc2VxKDIsIG5yb3codG9wMTBfZGYpKSkgew0KICBpZiAoKHRvcDEwX2RmJENvdW50cnlfUmVnaW9uW3hdID09IHRvcDEwX2RmJENvdW50cnlfUmVnaW9uW3gtMV0pICYgKHRvcDEwX2RmJENvdW50W3hdID49IDI1KSkgew0KICAgIGlmICh0b3AxMF9kZiRgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYFt4LTFdID09IDApew0KICAgICAgaWYgKHRvcDEwX2RmJERhaWx5X0NvdW50W3hdID4gMCkgew0KICAgICAgICB0b3AxMF9kZiRgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYFt4XSA8LSAxDQogICAgICB9DQogICAgfQ0KICAgIGVsc2Ugew0KICAgICAgaW50ZXJ2YWwgPC0gdG9wMTBfZGYkYERheXMgU2luY2UgRmlyc3QgQ2FzZWBbeC0xXQ0KICAgICAgdG9wMTBfZGYkYERheXMgU2luY2UgRmlyc3QgQ2FzZWBbeF0gPC0gMSArIGludGVydmFsDQogICAgfQ0KICB9DQp9DQoNCg0KdG9wMTBfZGYgPC0gbWVyZ2UodG9wMTBfZGYsY291bnRyeV9wb3AsYnk9YygnQ291bnRyeV9SZWdpb24nLCdDb3VudHJ5X1JlZ2lvbicpKQ0KdG9wMTBfZGYkUF9Db3VudCA8LSB0b3AxMF9kZiRDb3VudCAvIHRvcDEwX2RmJFBvcHVsYXRpb24NCnRvcDEwX2RmJFBfRGFpbHlfQ291bnQgPC0gdG9wMTBfZGYkRGFpbHlfQ291bnQgLyB0b3AxMF9kZiRQb3B1bGF0aW9uDQp0b3AxMF9kZiRQX1dlZWtseV9Db3VudCA8LSB0b3AxMF9kZiRXZWVrbHlfQ291bnQgLyB0b3AxMF9kZiRQb3B1bGF0aW9uDQp0b3AxMF9kZiA8LSB0b3AxMF9kZiAlPiUgc2VsZWN0KENvdW50cnlfUmVnaW9uLCBEYXRlLCBDb3VudCwgIFBfQ291bnQsIERhaWx5X0NvdW50LCBQX0RhaWx5X0NvdW50LCBXZWVrbHlfQ291bnQsIFBfV2Vla2x5X0NvdW50LCBgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYCkNCnRvcDEwX2RmIDwtIHRvcDEwX2RmW3dpdGgodG9wMTBfZGYsIG9yZGVyKENvdW50cnlfUmVnaW9uLCBEYXRlKSksIF0NCg0KYGBgDQoNCmBgYHtyIHRvdGFsX3Bsb3RseSwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTZ9DQp0b3AxMF9kZl93aWRlX3BfY291bnQgPC0gdG9wMTBfZGYgJT4lDQogIGZpbHRlcihgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYCAhPSAwKSAlPiUNCiAgc2VsZWN0KENvdW50cnlfUmVnaW9uLCBQX0NvdW50LCBgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYCkgJT4lDQogIHNwcmVhZChrZXk9Q291bnRyeV9SZWdpb24sIHZhbHVlPVBfQ291bnQpDQoNCnRvcDEwX2RmX3dpZGVfY291bnQgPC0gdG9wMTBfZGYgJT4lDQogIGZpbHRlcihgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYCAhPSAwKSAlPiUNCiAgc2VsZWN0KENvdW50cnlfUmVnaW9uLCBDb3VudCwgYERheXMgU2luY2UgRmlyc3QgQ2FzZWApICU+JQ0KICBzcHJlYWQoa2V5PUNvdW50cnlfUmVnaW9uLCB2YWx1ZT1Db3VudCkNCg0KDQpwYWxldHRlIDwtIGRpc3RpbmN0Q29sb3JQYWxldHRlKDIwKQ0KDQpmaWcgPC0gdG9wMTBfZGZfd2lkZV9jb3VudCAlPiUgcGxvdF9seSgpDQoNCmZvciAoayBpbiAyOmxlbmd0aCh0b3BfMTBfY291bnRyaWVzKSkgew0KICBjb3VudHJ5X2RmIDwtIGRhdGEuZnJhbWUoeT10b3AxMF9kZl93aWRlX2NvdW50W1trXV0sIHg9dG9wMTBfZGZfd2lkZV9jb3VudFtbMV1dKQ0KICBmaWcgPC0gYWRkX3RyYWNlKGZpZywgeT1+eSwgeD1+eCwgZGF0YT1jb3VudHJ5X2RmLCB0eXBlPSJzY2F0dGVyIiwgbW9kZT0ibGluZXMiLCBuYW1lID0gY29sbmFtZXModG9wMTBfZGZfd2lkZV9jb3VudClba10sIHZpc2libGUgPSBGLCBjb2xvciA9IHBhbGV0dGVba10pDQogIA0KICBwX2NvdW50cnlfZGYgPC0gZGF0YS5mcmFtZSh5PXRvcDEwX2RmX3dpZGVfcF9jb3VudFtba11dLCB4PXRvcDEwX2RmX3dpZGVfcF9jb3VudFtbMV1dKQ0KICBmaWcgPC0gYWRkX3RyYWNlKGZpZywgeT1+eSwgeD1+eCwgZGF0YT1wX2NvdW50cnlfZGYsIHR5cGU9InNjYXR0ZXIiLCBtb2RlPSJsaW5lcyIsIG5hbWUgPSBjb2xuYW1lcyh0b3AxMF9kZl93aWRlX3BfY291bnQpW2tdLCBjb2xvciA9IHBhbGV0dGVba10pDQp9DQoNCmZpZyA8LSBmaWcgJT4lIGxheW91dCgNCiAgICB0aXRsZSA9ICJUb3RhbCBDb25maXJtZWQgQ2FzZXMgU2luY2UgRmlyc3QgMjUgQ2FzZXMiLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZT0nRGF5cyBTaW5jZSBGaXJzdCAyNSBDYXNlcycpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJUb3RhbCBDb3VudCAoJSBvciAjKSIpLA0KICAgIHVwZGF0ZW1lbnVzID0gbGlzdCgNCiAgICAgIGxpc3QoDQogICAgICAgIHkgPSAwLjgsDQogICAgICAgIGJ1dHRvbnMgPSBsaXN0KA0KDQogICAgICAgICAgbGlzdChtZXRob2QgPSAicmVzdHlsZSIsDQogICAgICAgICAgICAgICBhcmdzID0gbGlzdCgidmlzaWJsZSIsIGMocmVwKGxpc3QoRkFMU0UsIFRSVUUpLCAxNSkpKSwNCiAgICAgICAgICAgICAgIGxhYmVsID0gIlBlcmNlbnQgQ291bnQiKSwNCg0KICAgICAgICAgIGxpc3QobWV0aG9kID0gInJlc3R5bGUiLA0KICAgICAgICAgICAgICAgYXJncyA9IGxpc3QoInZpc2libGUiLCBjKHJlcChsaXN0KFRSVUUsIEZBTFNFKSwgMTUpKSksDQogICAgICAgICAgICAgICBsYWJlbCA9ICJUb3RhbCBDb3VudCIpDQogICAgICAgICkNCiAgICAgICAgKQ0KICAgICAgKQ0KICAgICkNCg0KZmlnDQpgYGANCg0KYGBge3Igd2Vla2x5X3Bsb3RseSwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTZ9DQp0b3AxMF9kZl93aWRlX3Bfd2Vla2x5IDwtIHRvcDEwX2RmICU+JQ0KICBmaWx0ZXIoYERheXMgU2luY2UgRmlyc3QgQ2FzZWAgIT0gMCkgJT4lDQogIHNlbGVjdChDb3VudHJ5X1JlZ2lvbiwgUF9XZWVrbHlfQ291bnQsIGBEYXlzIFNpbmNlIEZpcnN0IENhc2VgKSAlPiUNCiAgc3ByZWFkKGtleT1Db3VudHJ5X1JlZ2lvbiwgdmFsdWU9UF9XZWVrbHlfQ291bnQpDQoNCnRvcDEwX2RmX3dpZGVfd2Vla2x5IDwtIHRvcDEwX2RmICU+JQ0KICBmaWx0ZXIoYERheXMgU2luY2UgRmlyc3QgQ2FzZWAgIT0gMCkgJT4lDQogIHNlbGVjdChDb3VudHJ5X1JlZ2lvbiwgV2Vla2x5X0NvdW50LCBgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYCkgJT4lDQogIHNwcmVhZChrZXk9Q291bnRyeV9SZWdpb24sIHZhbHVlPVdlZWtseV9Db3VudCkNCg0KDQpwYWxldHRlIDwtIGRpc3RpbmN0Q29sb3JQYWxldHRlKDIwKQ0KDQpmaWcgPC0gdG9wMTBfZGZfd2lkZV93ZWVrbHkgJT4lIHBsb3RfbHkoKQ0KDQpmb3IgKGsgaW4gMjpsZW5ndGgodG9wXzEwX2NvdW50cmllcykpIHsNCiAgY291bnRyeV9kZiA8LSBkYXRhLmZyYW1lKHk9dG9wMTBfZGZfd2lkZV93ZWVrbHlbW2tdXSwgeD10b3AxMF9kZl93aWRlX3dlZWtseVtbMV1dKQ0KICBmaWcgPC0gYWRkX3RyYWNlKGZpZywgeT1+eSwgeD1+eCwgZGF0YT1jb3VudHJ5X2RmLCB0eXBlPSJzY2F0dGVyIiwgbW9kZT0ibGluZXMiLCBuYW1lID0gY29sbmFtZXModG9wMTBfZGZfd2lkZV93ZWVrbHkpW2tdLCB2aXNpYmxlID0gRiwgY29sb3IgPSBwYWxldHRlW2tdKQ0KICANCiAgcF9jb3VudHJ5X2RmIDwtIGRhdGEuZnJhbWUoeT10b3AxMF9kZl93aWRlX3Bfd2Vla2x5W1trXV0sIHg9dG9wMTBfZGZfd2lkZV9wX3dlZWtseVtbMV1dKQ0KICBmaWcgPC0gYWRkX3RyYWNlKGZpZywgeT1+eSwgeD1+eCwgZGF0YT1wX2NvdW50cnlfZGYsIHR5cGU9InNjYXR0ZXIiLCBtb2RlPSJsaW5lcyIsIG5hbWUgPSBjb2xuYW1lcyh0b3AxMF9kZl93aWRlX3Bfd2Vla2x5KVtrXSwgY29sb3IgPSBwYWxldHRlW2tdKQ0KfQ0KDQpmaWcgPC0gZmlnICU+JSBsYXlvdXQoDQogICAgdGl0bGUgPSAiV2Vla2x5IENvbmZpcm1lZCBDYXNlcyBTaW5jZSBGaXJzdCAyNSBDYXNlcyIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlPSdEYXlzIFNpbmNlIEZpcnN0IDI1IENhc2VzJyksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIldlZWtseSBDb3VudCAoJSBvciAjKSIpLA0KICAgIHVwZGF0ZW1lbnVzID0gbGlzdCgNCiAgICAgIGxpc3QoDQogICAgICAgIHkgPSAwLjgsDQogICAgICAgIGJ1dHRvbnMgPSBsaXN0KA0KDQogICAgICAgICAgbGlzdChtZXRob2QgPSAicmVzdHlsZSIsDQogICAgICAgICAgICAgICBhcmdzID0gbGlzdCgidmlzaWJsZSIsIGMocmVwKGxpc3QoRkFMU0UsIFRSVUUpLCAxNSkpKSwNCiAgICAgICAgICAgICAgIGxhYmVsID0gIlBlcmNlbnQgQ291bnQiKSwNCg0KICAgICAgICAgIGxpc3QobWV0aG9kID0gInJlc3R5bGUiLA0KICAgICAgICAgICAgICAgYXJncyA9IGxpc3QoInZpc2libGUiLCBjKHJlcChsaXN0KFRSVUUsIEZBTFNFKSwgMTUpKSksDQogICAgICAgICAgICAgICBsYWJlbCA9ICJUb3RhbCBDb3VudCIpDQogICAgICAgICkNCiAgICAgICAgKQ0KICAgICAgKQ0KICAgICkNCg0KZmlnDQpgYGANCg0KDQoNCmBgYHtyIGRhaWx5X3Bsb3RseSwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTZ9ICANCg0KdG9wMTBfZGZfd2lkZV9wX2RhaWx5IDwtIHRvcDEwX2RmICU+JQ0KICBmaWx0ZXIoYERheXMgU2luY2UgRmlyc3QgQ2FzZWAgIT0gMCkgJT4lDQogIHNlbGVjdChDb3VudHJ5X1JlZ2lvbiwgUF9EYWlseV9Db3VudCwgYERheXMgU2luY2UgRmlyc3QgQ2FzZWApICU+JQ0KICBzcHJlYWQoa2V5PUNvdW50cnlfUmVnaW9uLCB2YWx1ZT1QX0RhaWx5X0NvdW50KQ0KDQp0b3AxMF9kZl93aWRlX2RhaWx5IDwtIHRvcDEwX2RmICU+JQ0KICBmaWx0ZXIoYERheXMgU2luY2UgRmlyc3QgQ2FzZWAgIT0gMCkgJT4lDQogIHNlbGVjdChDb3VudHJ5X1JlZ2lvbiwgRGFpbHlfQ291bnQsIGBEYXlzIFNpbmNlIEZpcnN0IENhc2VgKSAlPiUNCiAgc3ByZWFkKGtleT1Db3VudHJ5X1JlZ2lvbiwgdmFsdWU9RGFpbHlfQ291bnQpDQoNCg0KcGFsZXR0ZSA8LSBkaXN0aW5jdENvbG9yUGFsZXR0ZSgyMCkNCg0KZmlnIDwtIHRvcDEwX2RmX3dpZGVfZGFpbHkgJT4lIHBsb3RfbHkoKQ0KDQpmb3IgKGsgaW4gMjpsZW5ndGgodG9wXzEwX2NvdW50cmllcykpIHsNCiAgY291bnRyeV9kZiA8LSBkYXRhLmZyYW1lKHk9dG9wMTBfZGZfd2lkZV9kYWlseVtba11dLCB4PXRvcDEwX2RmX3dpZGVfZGFpbHlbWzFdXSkNCiAgZmlnIDwtIGFkZF90cmFjZShmaWcsIHk9fnksIHg9fngsIGRhdGE9Y291bnRyeV9kZiwgdHlwZT0ic2NhdHRlciIsIG1vZGU9ImxpbmVzIiwgbmFtZSA9IGNvbG5hbWVzKHRvcDEwX2RmX3dpZGVfZGFpbHkpW2tdLCB2aXNpYmxlID0gRiwgY29sb3IgPSBwYWxldHRlW2tdKQ0KICANCiAgcF9jb3VudHJ5X2RmIDwtIGRhdGEuZnJhbWUoeT10b3AxMF9kZl93aWRlX3BfZGFpbHlbW2tdXSwgeD10b3AxMF9kZl93aWRlX3BfZGFpbHlbWzFdXSkNCiAgZmlnIDwtIGFkZF90cmFjZShmaWcsIHk9fnksIHg9fngsIGRhdGE9cF9jb3VudHJ5X2RmLCB0eXBlPSJzY2F0dGVyIiwgbW9kZT0ibGluZXMiLCBuYW1lID0gY29sbmFtZXModG9wMTBfZGZfd2lkZV9wX2RhaWx5KVtrXSwgY29sb3IgPSBwYWxldHRlW2tdKQ0KfQ0KDQpmaWcgPC0gZmlnICU+JSBsYXlvdXQoDQogICAgdGl0bGUgPSAiRGFpbHkgQ29uZmlybWVkIENhc2VzIFNpbmNlIEZpcnN0IDI1IENhc2VzIiwNCiAgICB4YXhpcyA9IGxpc3QodGl0bGU9J0RheXMgU2luY2UgRmlyc3QgMjUgQ2FzZXMnKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRGFpbHkgQ291bnQgKCUgb3IgIykiKSwNCiAgICB1cGRhdGVtZW51cyA9IGxpc3QoDQogICAgICBsaXN0KA0KICAgICAgICB5ID0gMC44LA0KICAgICAgICBidXR0b25zID0gbGlzdCgNCg0KICAgICAgICAgIGxpc3QobWV0aG9kID0gInJlc3R5bGUiLA0KICAgICAgICAgICAgICAgYXJncyA9IGxpc3QoInZpc2libGUiLCBjKHJlcChsaXN0KEZBTFNFLCBUUlVFKSwgMTUpKSksDQogICAgICAgICAgICAgICBsYWJlbCA9ICJQZXJjZW50IENvdW50IiksDQoNCiAgICAgICAgICBsaXN0KG1ldGhvZCA9ICJyZXN0eWxlIiwNCiAgICAgICAgICAgICAgIGFyZ3MgPSBsaXN0KCJ2aXNpYmxlIiwgYyhyZXAobGlzdChUUlVFLCBGQUxTRSksIDE1KSkpLA0KICAgICAgICAgICAgICAgbGFiZWwgPSAiVG90YWwgQ291bnQiKQ0KICAgICAgICApDQogICAgICAgICkNCiAgICAgICkNCiAgICApDQoNCmZpZw0KYGBgDQoNCiMjIyBDT1ZJRDE5IENhc2VzIFNwcmVhZCBUaW1lbGFwc2UNCg0KVGhlIHRpbWUtbGFwc2Ugd2FzIHByb2R1Y2VkIHRocm91Z2ggZ2dhbmltYXRlIGFuZCBzaG93cyB0aGUgc3ByZWFkIG9mIHRoZSB2aXJ1cyBzaW5jZSAyMkphbjIwMjAuIFRoZSB0aW1lLWxhcHNlIGN5Y2xlcyB0aHJvdWdoIHRoZSBkYXRlcywgc2hvd2luZyB0aGUgY29sb3IgY29kZWQgaW5jcmVhc2Ugb2YgY29uZmlybWVkLCByZWNvdmVyZWQsIGFuZCBkZWF0aCBjYXNlcyBhY3Jvc3MgdGhlIHdvcmxkLg0KDQpgYGB7ciB0aW1lbGFwc19jYXNlcywgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBpbmNsdWRlPUZBTFNFfQ0KcCA8LSBnZ3Bsb3QoKSArDQogIGJvcmRlcnMoIndvcmxkIiwgY29sb3VyID0gIndoaXRlIiwgZmlsbCA9ICJncmF5ODUiKSArDQogIGNvb3JkX21hcCh4bGltID0gYygtMTgwLCAxODApLCB5bGltID0gYygtNTUsIDcwKSkgKw0KICB0aGVtZV9tYXAoKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihjdiwgRGF0ZTw9bGF0ZXN0X2RhdGUpLCBhZXMoeCA9IExvbmcsIHkgPSBMYXQsIHNpemUgPSBsb2cyKENvdW50KSwgY29sb3IgPSBTdGF0dXMpLCBhbHBoYSA9IDAuMjUpICsNCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKHJhbmdlID0gYygxLCAxNSkpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJsdWUiLCAicmVkIiwgImdyZWVuIikpICsNCiAgbGFicyh0aXRsZSA9ICJDT1ZJRDE5IExvZyBDb3VudCBvZiBDYXNlcyAoRGF0ZToge2ZyYW1lX3RpbWV9KSIsIHNpemUgPSAiTG9nKENhc2VzKSIpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0yNSwgZmFjZSA9ICJib2xkIiksDQogICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE3LCBmYWNlID0gImJvbGQiKQ0KICApICsNCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDUpKSwgc2l6ZSA9ICJub25lIikgKw0KICB0cmFuc2l0aW9uX3RpbWUoRGF0ZSkgKw0KICBlbnRlcl9mYWRlKCkgKw0KICBleGl0X2ZhZGUoKSArDQogIGVhc2VfYWVzKCJsaW5lYXIiKQ0KDQpkYXlzID0gYXMubnVtZXJpYyhsYXRlc3RfZGF0ZSAtIGFzLkRhdGUoIjIwMjAtMDEtMjIiKSkNCg0KYW5pbV9zYXZlKCJjb3ZpZDE5X3RpbWVsYXBzZS5naWYiLCBwLCBoZWlnaHQgPSA2MDAsIHdpZHRoID0gMTAwMCwgZnBzID0gMTAsIG5mcmFtZXMgPSBkYXlzKjIsIGVuZF9wYXVzZSA9IDMwKQ0KYGBgDQohW10oY292aWQxOV90aW1lbGFwc2UuZ2lmKQ0KDQojIyMgTmV3IENhc2VzIG9mIHRoZSBEYXkgKGByIGxhdGVzdF9kYXRlYCkNCg0KVGhlICdOZXcgQ2FzZXMgb2YgdGhlIERheScgbWFwIGRpc3BsYXlzIGFsbCBjb25maXJtZWQgY2FzZXMgb2YgdGhlIHNwZWNpZmllZCBkYXRlLiBUaGUgbWFwIHdhcyBwcm9kdWNlZCB0aHJvdWdoIExlYWZsZXQgYW5kIHByb3ZpZGVzIGEgZGV0YWlsZWQgYW5kIGludGVyYWN0aXZlIG1hcCB0aGF0IHNob3dzIHRoZSBsb2NhdGlvbiBhbmQgbnVtYmVyIG9mIGNhc2VzIG9mIHRoZSBkYXkuDQoNCkFsc28sIHRvIGRpZmZlcmVudGlhdGUgaWYgdGhlIGNhc2Ugb2YgdGhlIGRheSBpcyB0aGUgZmlyc3QgY2FzZSBpbiB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uLCBpdCBpcyBoaWdobGlnaHRlZCByZWQuIEFsbCB0aGUgc3BlY2lmaWVkIHBvaW50cyBvbiB0aGUgbWFwIGFyZSBsaXN0ZWQgaW4gdGhlIHRhYmxlIGJlbG93LCBpbmNsdWRpbmcgY3VtdWxhdGl2ZSBjb3VudCBvZiBlYWNoIGxvY2F0aW9uLg0KDQoNCmBgYHtyIGRheV9sZWFmbHlfcGxvdCwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmZpcnN0X2NvbG9yIDwtIGNvbG9yRmFjdG9yKHBhbGV0dGUgPSBjKCJyZWQiLCAiYmx1ZSIpLCBsZXZlbHMgPSBjKFRSVUUsIEZBTFNFKSkNCg0KbmV3X2RheV9sYWJlbHMgPC0gZnVuY3Rpb24oZGYpIHsNCiAgbGFicyA8LSBsYXBwbHkoc2VxKG5yb3coZGYpKSwgZnVuY3Rpb24oaSkgew0KICAgIHBhc3RlMCgNCiAgICAgICJDb3VudHJ5OiAiLCBkZltpLCAiQ291bnRyeV9SZWdpb24iXSwgIjxicj4gIiwNCiAgICAgICJQcm92aW5jZTogIiwgZGZbaSwgIlByb3ZpbmNlX1N0YXRlIl0sICI8YnI+IiwNCiAgICAgICJEYXkgQ291bnQ6ICIsIGRmW2ksICJEYWlseV9Db3VudCJdLCAiPGJyPiIsDQogICAgICAiRmlyc3QgQ2FzZTogIiwgZGZbaSwgIkZpcnN0X0Nhc2UiXSwgIjxicj4iLA0KICAgICAgIkRhdGU6ICIsIGRmW2ksICJEYXRlIl0NCiAgICApDQogIH0pDQp9DQoNCmxlYWZsZXQoZGF0YSA9IG5ld19jYXNlc19kYXksIHdpZHRoID0gIjEwMCUiKSAlPiUNCiAgYWRkVGlsZXMoKSAlPiUNCiAgYWRkQ2lyY2xlTWFya2VycygNCiAgICBsYXQgPSB+TGF0LA0KICAgIGxuZyA9IH5Mb25nLA0KICAgIHJhZGl1cyA9IH4gbG9nKENvdW50KSAvIDEuMjUsDQogICAgbGFiZWwgPSBsYXBwbHkobmV3X2RheV9sYWJlbHMobmV3X2Nhc2VzX2RheSksIGh0bWx0b29sczo6SFRNTCksDQogICAgY29sb3IgPSB+IGZpcnN0X2NvbG9yKEZpcnN0X0Nhc2UpDQogICkgJT4lDQogIGFkZExlZ2VuZCgiYm90dG9tcmlnaHQiLA0KICAgIHBhbCA9IGZpcnN0X2NvbG9yLCB2YWx1ZXMgPSB+Rmlyc3RfQ2FzZSwNCiAgICB0aXRsZSA9ICJGaXJzdCBDYXNlIChEYXkpIiwNCiAgICBvcGFjaXR5ID0gMC43NQ0KICApDQpgYGANCg0KYGBge3IgZGF5X3RhYmxlX25ldywgZWNobz1GQUxTRX0NCmRmX25ld19jYXNlc19kYXkgPC0gbmV3X2Nhc2VzX2RheSAlPiUNCiAgc2VsZWN0KA0KICAgIERhdGUsIENvdW50cnlfUmVnaW9uLCBQcm92aW5jZV9TdGF0ZSwNCiAgICBDb3VudCwgRGFpbHlfQ291bnQsIFdlZWtseV9Db3VudCwgRmlyc3RfQ2FzZQ0KICApDQpkZl9uZXdfY2FzZXNfZGF5DQpgYGANCg0KIyMjIE5ldyBDYXNlcyBvZiB0aGUgV2VlayAoYHIgbGF0ZXN0X2RhdGVgKQ0KDQpUaGUgJ05ldyBDYXNlcyBvZiB0aGUgV2VlaycgbWFwIGRpc3BsYXlzIGFsbCBjb25maXJtZWQgY2FzZXMgb2YgdGhlIHdlZWsgc3RhcnRpbmcgZnJvbSB0aGUgc3BlY2lmaWVkIGRhdGUuIFRoaXMgbWFwIHNob3dzIHRoZSBzYW1lIGluZm9ybWF0aW9uIGFzIHRoZSBkYWlseSBjYXNlcyBtYXAgYnV0IGluY2x1ZGVzIGFsbCBjYXNlcyBpbiB0aGUgcGFzdCB3ZWVrLg0KDQpgYGB7ciB3ZWVrX2xlYWZseV9wbG90LCBlY2hvPUZBTFNFfQ0KZmlyc3RfY29sb3IgPC0gY29sb3JGYWN0b3IocGFsZXR0ZSA9IGMoInJlZCIsICJibHVlIiksIGxldmVscyA9IGMoVFJVRSwgRkFMU0UpKQ0KDQpuZXdfd2Vla19sYWJlbHMgPC0gZnVuY3Rpb24oZGYpIHsNCiAgbGFicyA8LSBsYXBwbHkoc2VxKG5yb3coZGYpKSwgZnVuY3Rpb24oaSkgew0KICAgIHBhc3RlMCgNCiAgICAgICJDb3VudHJ5OiAiLCBkZltpLCAiQ291bnRyeV9SZWdpb24iXSwgIjxicj4gIiwNCiAgICAgICJQcm92aW5jZTogIiwgZGZbaSwgIlByb3ZpbmNlX1N0YXRlIl0sICI8YnI+IiwNCiAgICAgICJXZWVrIENvdW50OiAiLCBkZltpLCAiV2Vla2x5X0NvdW50Il0sICI8YnI+IiwNCiAgICAgICJGaXJzdCBDYXNlOiAiLCBkZltpLCAiRmlyc3RfQ2FzZSJdLCAiPGJyPiIsDQogICAgICAiRGF0ZTogIiwgZGZbaSwgIkRhdGUiXQ0KICAgICkNCiAgfSkNCn0NCg0KbGVhZmxldChkYXRhID0gbmV3X2Nhc2VzX3dlZWssIHdpZHRoID0gIjEwMCUiKSAlPiUNCiAgYWRkVGlsZXMoKSAlPiUNCiAgYWRkQ2lyY2xlTWFya2VycygNCiAgICBsYXQgPSB+TGF0LA0KICAgIGxuZyA9IH5Mb25nLA0KICAgIHJhZGl1cyA9IH4gbG9nKENvdW50KSAvIDEuMjUsDQogICAgbGFiZWwgPSBsYXBwbHkobmV3X3dlZWtfbGFiZWxzKG5ld19jYXNlc193ZWVrKSwgaHRtbHRvb2xzOjpIVE1MKSwNCiAgICBjb2xvciA9IH4gZmlyc3RfY29sb3IoRmlyc3RfQ2FzZSkNCiAgKSAlPiUNCiAgYWRkTGVnZW5kKCJib3R0b21yaWdodCIsDQogICAgcGFsID0gZmlyc3RfY29sb3IsIHZhbHVlcyA9IH5GaXJzdF9DYXNlLA0KICAgIHRpdGxlID0gIkZpcnN0IENhc2UgKFdlZWspIiwNCiAgICBvcGFjaXR5ID0gMC43NQ0KICApDQpgYGANCg0KYGBge3Igd2Vla190YWJsZV9uZXcsIGVjaG89RkFMU0V9DQpkZl9uZXdfY2FzZXNfd2VlayA8LSBuZXdfY2FzZXNfd2VlayAlPiUNCiAgc2VsZWN0KA0KICAgIERhdGUsIENvdW50cnlfUmVnaW9uLCBQcm92aW5jZV9TdGF0ZSwNCiAgICBDb3VudCwgRGFpbHlfQ291bnQsIFdlZWtseV9Db3VudCwgRmlyc3RfQ2FzZQ0KICApDQpkZl9uZXdfY2FzZXNfd2Vlaw0KYGBgDQoNCmBgYHtyIGNhc2VzX2NvdW50X3BlcmNlbnRfYWdnLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCnBlcmNlbnRfY291bnQgPC0gY3ZfbWVyZ2UgJT4lDQogIGdyb3VwX2J5KERhdGUpICU+JQ0KICBmaWx0ZXIoRGF0ZSA8PSBsYXRlc3RfZGF0ZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBDb25maXJtZWQgPSBzdW0oQ29uZmlybWVkLCBuYS5ybSA9IFRSVUUpLA0KICAgIERlYWQgPSBzdW0oRGVhZCwgbmEucm0gPSBUUlVFKSwNCiAgICBSZWNvdmVyZWQgPSBzdW0oUmVjb3ZlcmVkLCBuYS5ybSA9IFRSVUUpDQogICkNCmZvciAoeCBpbiBzZXEoMSwgbnJvdyhwZXJjZW50X2NvdW50KSkpIHsNCiAgaWYgKHggPT0gMSkgew0KICAgIHBlcmNlbnRfY291bnQkRGFpbHlfQ29uZmlybWVkW3hdIDwtIHBlcmNlbnRfY291bnQkQ29uZmlybWVkW3hdDQogICAgcGVyY2VudF9jb3VudCREYWlseV9EZWFkW3hdIDwtIHBlcmNlbnRfY291bnQkRGVhZFt4XQ0KICAgIHBlcmNlbnRfY291bnQkRGFpbHlfUmVjb3ZlcmVkW3hdIDwtIHBlcmNlbnRfY291bnQkUmVjb3ZlcmVkW3hdDQogIH0NCiAgZWxzZSB7DQogICAgcGVyY2VudF9jb3VudCREYWlseV9Db25maXJtZWRbeF0gPC0gcGVyY2VudF9jb3VudCRDb25maXJtZWRbeF0gLSBwZXJjZW50X2NvdW50JENvbmZpcm1lZFt4IC0gMV0NCiAgICBwZXJjZW50X2NvdW50JERhaWx5X0RlYWRbeF0gPC0gcGVyY2VudF9jb3VudCREZWFkW3hdIC0gcGVyY2VudF9jb3VudCREZWFkW3ggLSAxXQ0KICAgIHBlcmNlbnRfY291bnQkRGFpbHlfUmVjb3ZlcmVkW3hdIDwtIHBlcmNlbnRfY291bnQkUmVjb3ZlcmVkW3hdIC0gcGVyY2VudF9jb3VudCRSZWNvdmVyZWRbeCAtIDFdDQogIH0NCn0NCg0KZGVhZF9jb25mX3JlY3YgPC0gcGVyY2VudF9jb3VudCAlPiUNCiAgc2VsZWN0KERhdGUsIENvbmZpcm1lZCwgRGVhZCwgUmVjb3ZlcmVkKSAlPiUNCiAgZ2F0aGVyKGtleT0iU3RhdHVzIiwgdmFsdWU9IkNvdW50IiwgLURhdGUpDQoNCmRlYWRfY29uZl9yZWN2X2RhaWx5IDwtIHBlcmNlbnRfY291bnQgJT4lDQogIHNlbGVjdChEYXRlLCBEYWlseV9Db25maXJtZWQsIERhaWx5X0RlYWQsIERhaWx5X1JlY292ZXJlZCkgJT4lDQogIGdhdGhlcihrZXk9IkRhaWx5IiwgdmFsdWU9IkNvdW50IiwgLURhdGUpDQoNCnBlcmNlbnRfY291bnQkUGVyY2VudF9EZWFkIDwtIHBlcmNlbnRfY291bnQkRGVhZCAvIHBlcmNlbnRfY291bnQkQ29uZmlybWVkDQoNCnBlcmNlbnRfY291bnQkUGVyY2VudF9SZWNvdmVyZWQgPC0gcGVyY2VudF9jb3VudCRSZWNvdmVyZWQgLyBwZXJjZW50X2NvdW50JENvbmZpcm1lZA0KDQpwZXJjZW50X29yZyA8LSBwZXJjZW50X2NvdW50ICU+JQ0KICBzZWxlY3QoRGF0ZSwgUGVyY2VudF9SZWNvdmVyZWQsIFBlcmNlbnRfRGVhZCkgJT4lDQogIGdhdGhlcihrZXk9IlN0YXR1cyIsIHZhbHVlPSJQZXJjZW50IiwgLURhdGUpIA0KYGBgDQoNCiMjIyBHZW5lcmFsIFRyZW5kcw0KDQpUaGUgcGxvdHMgYmVsb3cgb3V0bGluZXMgZ2VuZXJhbCB0cmVuZHMgc2VlbiBvZiB0aGUgdmlydXMgb3ZlciB0aW1lOg0KDQooMSkJ4oCcUGVyY2VudCBvZiBDYXNlcyBSZWNvdmVyZWQgb3IgRGVhZCBwZXIgRGF54oCdOiB0aGUgdG90YWwgcGVyY2VudCBvZiBjYXNlcyB0aGF0IGhhdmUgcmVzdWx0ZWQgaW4gcmVjb3Zlcnkgb3IgZGVhdGggcGVyIGNvbmZpcm1lZCBjYXNlDQoNCigyKQkiQ3VtdWxhdGl2ZSBTdGF0dXMgb2YgQWxsIENhc2VzIjogdGhlIGNvbnRpbnVvdXMgaW5jcmVhc2Ugb2YgY29uZmlybWVkLCBkZWF0aCwgYW5kIHJlY292ZXJlZCBjYXNlcyBvdmVyIHRpbWUgDQoNCigzKQnigJxTdGF0dXMgb2YgQ2FzZXMgcGVyIERheeKAnTogdGhlIG51bWJlciBvZiBjYXNlcyBjbGFzc2lmaWVkIGFzIGNvbmZpcm1lZCwgZGVhdGgsIG9yIHJlY292ZXJlZCBzdWJ0cmFjdGVkIHRvIHNob3cgcGVyIGRheSBjaGFuZ2VzDQoNCmBgYHtyIHBsb3RfcGVyY2VudF9jYXNlcywgZWNobz1GQUxTRSwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NC41fQ0KZ2dwbG90KHBlcmNlbnRfb3JnLCBhZXMoeCA9IERhdGUsIHk9UGVyY2VudCwgZ3JvdXA9U3RhdHVzKSkgKw0KICBnZW9tX2xpbmUoYWVzKGNvbG9yID0gU3RhdHVzKSwgc2l6ZT0xLjMpICsNCiAgZ2d0aXRsZSgiUGVyY2VudCBvZiBDYXNlcyBSZWNvdmVyZWQgb3IgRGVhZCBwZXIgRGF5IikgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygicmVkMyIsICJncmVlbjMiKSkgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiNyBkYXkiLCANCiAgICAgICAgICAgICAgIGRhdGVfbWlub3JfYnJlYWtzID0gIjcgZGF5IiwgDQogICAgICAgICAgICAgICBkYXRlX2xhYmVscyA9ICIlYiAlZCIpICsNCiAgdGhlbWVfbGlnaHQoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCmBgYHtyIHBsb3RfY3VtdWxhdGl2ZV9zdGF0dXMsIGVjaG89RkFMU0UsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTQuNX0NCmdncGxvdChkZWFkX2NvbmZfcmVjdiwgYWVzKHggPSBEYXRlLCB5PUNvdW50LCBncm91cD1TdGF0dXMpKSArDQogIGdlb21fbGluZShhZXMoY29sb3IgPSBTdGF0dXMpLCBzaXplPTEuMykgKw0KICBnZ3RpdGxlKCJDdW11bGF0aXZlIFN0YXR1cyBvZiBBbGwgQ2FzZXMiKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJibHVlMyIsICJyZWQzIiwgImdyZWVuMyIpKSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICI3IGRheSIsIA0KICAgICAgICAgICAgICAgZGF0ZV9taW5vcl9icmVha3MgPSAiNyBkYXkiLCANCiAgICAgICAgICAgICAgIGRhdGVfbGFiZWxzID0gIiViICVkIikgKw0KICB0aGVtZV9saWdodCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCg0KDQpgYGB7ciBwbG90X3N0YXR1c19wZXJfZGF5LCBlY2hvPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00LjV9ICANCmdncGxvdChkZWFkX2NvbmZfcmVjdl9kYWlseSwgYWVzKHggPSBEYXRlLCB5PUNvdW50LCBncm91cD1EYWlseSkpICsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IERhaWx5KSwgc2l6ZT0xLjMpICsNCiAgZ2d0aXRsZSgiU3RhdHVzIG9mIENhc2VzIHBlciBEYXkiKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJibHVlMyIsICJyZWQzIiwgImdyZWVuMyIpKSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICI3IGRheSIsIA0KICAgICAgICAgICAgICAgZGF0ZV9taW5vcl9icmVha3MgPSAiNyBkYXkiLCANCiAgICAgICAgICAgICAgIGRhdGVfbGFiZWxzID0gIiViICVkIikrDQogIHRoZW1lX2xpZ2h0KCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkNCmBgYA0KDQpgYGB7ciBnaXRodWJfcHVzaGluZ19jb21tYW5kcywgaW5jbHVkZT1GQUxTRX0NCmdpdHN0YXR1cyA8LSBmdW5jdGlvbihkaXIgPSBnZXR3ZCgpKSB7DQogIGNtZF9saXN0IDwtIGxpc3QoDQogICAgY21kMSA9IHRvbG93ZXIoc3Vic3RyKGRpciwgMSwgMikpLA0KICAgIGNtZDIgPSBwYXN0ZSgiY2QiLCBkaXIpLA0KICAgIGNtZDMgPSAiZ2l0IHN0YXR1cyINCiAgKQ0KICBjbWQgPC0gcGFzdGUodW5saXN0KGNtZF9saXN0KSwgY29sbGFwc2UgPSAiICYgIikNCiAgc2hlbGwoY21kKQ0KfQ0KDQpnaXRhZGQgPC0gZnVuY3Rpb24oZGlyID0gZ2V0d2QoKSkgew0KICBjbWRfbGlzdCA8LSBsaXN0KA0KICAgIGNtZDEgPSB0b2xvd2VyKHN1YnN0cihkaXIsIDEsIDIpKSwNCiAgICBjbWQyID0gcGFzdGUoImNkIiwgZGlyKSwNCiAgICBjbWQzID0gImdpdCBhZGQgLS1hbGwiDQogICkNCiAgY21kIDwtIHBhc3RlKHVubGlzdChjbWRfbGlzdCksIGNvbGxhcHNlID0gIiAmICIpDQogIHNoZWxsKGNtZCkNCn0NCg0KZ2l0Y29tbWl0IDwtIGZ1bmN0aW9uKG1zZyA9IHBhc3RlKCJjaG9yZTogYXV0by11cGRhdGUiLCBTeXMudGltZSgpLCAiZXN0IiksIGRpciA9IGdldHdkKCkpIHsNCiAgY21kIDwtIHNwcmludGYoImdpdCBjb21taXQgLW1cIiVzXCIiLCBtc2cpDQogIHN5c3RlbShjbWQpDQp9DQoNCmdpdHB1c2ggPC0gZnVuY3Rpb24oZGlyID0gZ2V0d2QoKSkgew0KICBjbWRfbGlzdCA8LSBsaXN0KA0KICAgIGNtZDEgPSB0b2xvd2VyKHN1YnN0cihkaXIsIDEsIDIpKSwNCiAgICBjbWQyID0gcGFzdGUoImNkIiwgZGlyKSwNCiAgICBjbWQzID0gImdpdCBwdXNoIg0KICApDQogIGNtZCA8LSBwYXN0ZSh1bmxpc3QoY21kX2xpc3QpLCBjb2xsYXBzZSA9ICIgJiAiKQ0KICBzaGVsbChjbWQpDQp9DQoNCmdpdDJyOjpjb25maWcodXNlci5uYW1lID0gImFsYmVjaGVuIiwgdXNlci5lbWFpbCA9ICJhbGNoZW4yNDRAZ21haWwuY29tIikNCmBgYA0KDQpgYGB7ciBzYXZlX2RvYywgaW5jbHVkZT1GQUxTRX0NCmRvY3VtZW50U2F2ZShnZXRBY3RpdmVEb2N1bWVudENvbnRleHQoKSkNClN5cy5zbGVlcCgyMCkNCmBgYA0KDQpgYGB7ciBnaXRodWJfcHVzaF9hbGwsIGluY2x1ZGU9RkFMU0V9DQpnaXRzdGF0dXMoKQ0KZ2l0YWRkKCkNCmdpdGNvbW1pdCgpDQpnaXRwdXNoKCkNCmBgYA0K